/**
 * 印章去背景
 * @author ldy
 */
class SealMatting {
  constructor(file) {
    this.file = file
  }
  createStream() {
    let reader = new FileReader()
    let ext = this.file.name.substring(this.file.name.lastIndexOf('.') + 1).toLowerCase()
    if (ext !== 'png' && ext !== 'jpg' && ext !== 'jpeg') {
      alert('图片的格式必须为png或者jpg或者jpeg格式！')
      return
    }
    reader.onload = (e) => {
      let src = e.target.result
      let img = new Image()
      img.src = src
      img.onload = () => {
        let w = img.width
        let h = img.height
        this.fitch(w, h, img)
      }
    }
    reader.readAsDataURL(this.file)
  }
  fitch(width, height, img) {
    let dataUrl
    let c = document.createElement('canvas')
    c.width = width
    c.height = height
    let ctx = c.getContext('2d')
    ctx.drawImage(img, 0, 0)
    let isPNG = true // 判断是否已经扣过
    let imgDataUrl = ctx.getImageData(0, 0, width, height) // 获取像素点
    let data = imgDataUrl.data
    for (let i = 0; i < data.length; i += 4) {
      // 得到 RGBA 通道的值
      let r = data[i]
      let g = data[i + 1]
      let b = data[i + 2]
      if (data[i + 3] === 0) {
        isPNG = false
      }
      // 非红色去背景
      if (Math.abs(r - g) < 20 && Math.abs(r - b) < 20) {
        // 红色
        data[i + 3] = 0 // 设置背景透明
      }
      // 蓝色
      if (Math.abs(b - r) < 25 && Math.abs(b - g) < 25) {
        // 蓝色
        data[i + 3] = 0 // 设置背景透明
      }
      // 黑色
      if (r < 120 && g < 120 && b < 120) {
        // 黑色
        data[i + 3] = 0 // 设置背景透明
      }
    }
    // 将修改后的代码复制回画布中
    ctx.putImageData(imgDataUrl, 0, 0)
    let resImgData = ctx.getImageData(0, 0, width, height)
    // 图片裁剪转换
    dataUrl = this.convert(ctx, width, height, resImgData.data)
    if (isPNG) {
      /**
             * 创建下载链接 进行图片下载
             * @type {Element}
             */
      let a = document.createElement('a')
      a.href = dataUrl // 下载图片
      a.download = '未命名.png'
      a.click()
    } else {
      alert('背景已抠除！')
    }
  }
  /**
     * 转换图片
     * @param {*} context
     * @param {*} width
     * @param {*} height
     * @param {*} data
     */
  convert(context, width, height, data) {
    let cropArea = this.getCropArea(data, width, height)
    let cropCanvas = document.createElement('canvas')
    const cropCtx = cropCanvas.getContext('2d')
    cropCanvas.width = cropArea[2] - cropArea[0]
    cropCanvas.height = cropArea[3] - cropArea[1]
    const cropImgData = context.getImageData(...cropArea)
    cropCtx.globalCompositeOperation = 'destination-over'
    cropCtx.putImageData(cropImgData, 0, 0)
    cropCtx.fillStyle = 'rgba(255, 255, 255, 0)'
    cropCtx.fillRect(0, 0, cropCanvas.width, cropCanvas.height)
    return cropCanvas.toDataURL('image/png', 100)
  }
  /**
     * 裁剪
     * @param {*} imgData
     * @param {*} width
     * @param {*} height
     */
  getCropArea(imgData, width, height) {
    let topX = width
    let btmX = 0
    let topY = height
    let btnY = 0
    for (let i = 0; i < width; i++) {
      for (let j = 0; j < height; j++) {
        let pos = (i + width * j) * 4
        if (
          imgData[pos] > 0 ||
                    imgData[pos + 1] > 0 ||
                    imgData[pos + 2] ||
                    imgData[pos + 3] > 0
        ) {
          btnY = Math.max(j, btnY)
          btmX = Math.max(i, btmX)
          topY = Math.min(j, topY)
          topX = Math.min(i, topX)
        }
      }
    }
    topX++
    btmX++
    topY++
    btnY++
    const data = [topX, topY, btmX, btnY]
    return data
  }
}
export default SealMatting
